package org.udr.query;

import java.util.ArrayList;
import java.util.List;

import org.udr.datamodel.Association;
import org.udr.datamodel.Attribute;
import org.udr.datamodel.Entity;
import org.udr.datamodel.Property;

public class QueryTreeNode {

	private static final String THIS_ALIAS = "this";
	private static final String ALIAS_DESCRIMINATOR = "$";
	private static final String PATH_DESCRIMINATOR = ".";

	protected final QueryTreeNode parent;
	private final List<QueryTreeNode> children = new ArrayList<QueryTreeNode>();
	private final String text;
	private final String name;
	private final String path;
	private final String alias;
	private final Object dataModelElement;
	private Object queryElement;

	public QueryTreeNode(Entity rootEntity) {
		this(rootEntity, null, rootEntity.getName(), rootEntity.getName(),
				rootEntity.getName(), THIS_ALIAS);
	}

	public QueryTreeNode(QueryTreeNode parentNode, Association association) {
		this(association, parentNode, association.getName(), association
				.getName(), generatePath(parentNode, association),
				generateAlias(parentNode, association));
	}

	public QueryTreeNode(QueryTreeNode parentNode, Property property) {
		this(property, parentNode, property.getName(), property.getName(),
				generatePath(parentNode, property), property.getName());
	}

	private static String generatePath(QueryTreeNode parentNode,
			Attribute attribute) {
		return parentNode.getAlias() + PATH_DESCRIMINATOR + attribute.getName();
	}

	private static String generateAlias(QueryTreeNode parentNode,
			Association association) {
		return parentNode.getAlias() + ALIAS_DESCRIMINATOR
				+ association.getName();
	}

	private QueryTreeNode(Object dataModelElement, QueryTreeNode parent,
			String text, String name, String path, String alias) {
		this.dataModelElement = dataModelElement;
		this.parent = parent;
		this.text = text;
		this.name = name;
		this.path = path;
		this.alias = alias;
	}

	public String getText() {
		return text;
	}

	public QueryTreeNode getParent() {
		return parent;
	}

	public void addChild(QueryTreeNode childNode) {
		this.children.add(childNode);
	}

	public boolean hasChildren() {
		return !children.isEmpty();
	}

	public List<QueryTreeNode> getChildren() {
		return children;
	}

	public String getName() {
		return name;
	}

	public String getAlias() {
		return alias;
	}

	public Object getDataModelElement() {
		return dataModelElement;
	}

	public Object getQueryElement() {
		return queryElement;
	}

	public void setQueryElement(Object queryElement) {
		this.queryElement = queryElement;
	}

	public String getPath() {
		return path;
	}
}
